package cn.ac.iscas.bean.base;


import java.util.LinkedHashMap;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.ac.iscas.bean.QueryResult;


@SuppressWarnings("unchecked")
@Service @Transactional
public abstract class DAOSupport<T> implements DAO<T>{
	@Resource protected SessionFactory sessionFactory;
	public void clear(){
	     sessionFactory.getCurrentSession().clear();
	}

	public void delete(Object entity) {		
		    sessionFactory.getCurrentSession().delete(entity);	
	}
	
	
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public T get(Class<T> entityClass,int entityId) {
		
		return (T) sessionFactory.getCurrentSession().get(entityClass,entityId);
	}

	public void save(Object entity) {
		sessionFactory.getCurrentSession().save(entity);
	}
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public long getCount(Class<T> entityClass){
		return ((Long)sessionFactory.getCurrentSession().createQuery("select count(o) from "+ entityClass.getSimpleName()+ " o").uniqueResult()).longValue();

	}
	
	public void update(Object entity) {
		sessionFactory.getCurrentSession().update(entity);
	}
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult, LinkedHashMap<String, String> orderby) {
		return getScrollData(entityClass,firstindex,maxresult,null,null,orderby);
	}
	
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult, String wherejpql, Object[] queryParams) {
		return getScrollData(entityClass,firstindex,maxresult,wherejpql,queryParams,null);
	}
	
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult) {
		return getScrollData(entityClass,firstindex,maxresult,null,null,null);
	}
	
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public QueryResult<T> getScrollData(Class<T> entityClass) {
		return getScrollData(entityClass,-1, -1);
	}

	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int maxresult
			, String wherejpql, Object[] queryParams,LinkedHashMap<String, String> orderby) {
		QueryResult qr = new QueryResult<T>();
		String entityname = entityClass.getSimpleName();
		Query query =sessionFactory.getCurrentSession().createQuery("select o from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where "+ wherejpql)+ buildOrderby(orderby));
		setQueryParams(query, queryParams);
		if(firstindex!=-1 && maxresult!=-1) query.setFirstResult(firstindex).setMaxResults(maxresult);
		qr.setResultlist(query.list());
		query = sessionFactory.getCurrentSession().createQuery("select count(o) from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where "+ wherejpql));
		setQueryParams(query, queryParams);
		qr.setTotalrecord(((Long)query.uniqueResult()).longValue());
		return qr;
	}	
	
	public QueryResult<T> getScrollData(String sql,String countSql,int firstindex, int maxresult){
		QueryResult qr = new QueryResult<T>();
		
		
		Query query = sessionFactory.getCurrentSession().createSQLQuery(sql);
		if(firstindex!=-1 && maxresult!=-1) query.setFirstResult(firstindex).setMaxResults(maxresult);
		qr.setResultlist(query.list());
		System.out.println("sql:::"+sql);
		query = sessionFactory.getCurrentSession().createSQLQuery(countSql);
		qr.setTotalrecord(((Long)query.uniqueResult()).longValue());
		System.out.println(countSql);
		return qr;
	}
	
	protected static void setQueryParams(Query query, Object[] queryParams){
		if(queryParams!=null && queryParams.length>0){
			for(int i=0; i<queryParams.length; i++){
				query.setParameter(i, queryParams[i]);
			}
		}
	}
	/**
	 * 组装order by语句
	 * @param orderby
	 * @return
	 */
	 protected static String buildOrderby(LinkedHashMap<String, String> orderby){
		StringBuffer orderbyql = new StringBuffer("");
		if(orderby!=null && orderby.size()>0){
			orderbyql.append(" order by ");
			for(String key : orderby.keySet()){
				orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
			}
			orderbyql.deleteCharAt(orderbyql.length()-1);
		}
		return orderbyql.toString();
	}	
	
}
